﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2011-03-09
//
// Update Date : 
//
// Copyright (c) Fuel Game Engine (http://www.fge-engine.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


//----------------------------------------------------------------
//
//----------------------------------------------------------------
enum EF_GUI_TYPE
{
    eGT_Picture,
    eGT_Text,
    eGT_Button,
    eGT_List,
    eGT_Guage,
};
enum EF_GUI_EVENT
{
    eGE_Click,
};
class FGUI;


typedef bool (FCALL *FGUIFunc)(DWORD ui_id, DWORD msg, DWORD param);


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUIObject : public IFMemObject
{
    friend class FGUI;

    FDECLARE_CLASS(FGUIObject)

public:
    DWORD ID(){ return nID; }
    void SetBack(IFSpriteObject* spr){ pBack = spr; }
    IFSpriteObject* GetBack(){ return pBack; }
    bool IsIn(float x, float y){ return dstRect.inside(x, y); }
    void SetDstRect(float dx, float dy, float dw, float dh)
        { dstRect.X = dx, dstRect.Y = dy, dstRect.W = dw, dstRect.H = dh;}
    void SetVisible(bool v){ bVisible = v; }
    bool IsVisible(){ return bVisible; }
    void SetEnable(bool e){ bEnable = e; }
    bool IsEnable(){ return bEnable; }
    void SetData(DWORD d){ nData = d; }
    DWORD GetData(){ return nData; }

protected:
    FGUIObject();

    virtual void Update(){}
    virtual void Render();
    virtual void RenderText(){}

    virtual bool MouseOver(bool into){ return false; }
    virtual bool MouseWheel(int nNotches){ return false; }
    virtual bool LButton(bool down){ return false; }
    virtual bool RButton(bool down){ return false; }
    virtual bool KeyEvent(bool down, int key){ return false; }
    virtual void Move(float x, float y){ dstRect.X += x; dstRect.Y += y; }
    virtual void MoveTo(float x, float y){ dstRect.X = x; dstRect.Y = y; }

    DWORD nID;
    FRect dstRect;
    IFSpriteObject* pBack;
    FGUIObject* pPrev,* pNext;
    bool bVisible, bEnable;
    FGUI* pGUI;
    DWORD nData;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUIButton : public FGUIObject
{
    friend class FGUI;

    FDECLARE_CLASS(FGUIButton)

public:
    void SetSuspend(IFSpriteObject* spr){ pSuspend = spr; }
    void Render();

protected:
    FGUIButton()
        :pSuspend(0)
    {}

    IFSpriteObject* pSuspend;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUIList : public FGUIObject
{
    friend class FGUI;

    FDECLARE_CLASS(FGUIList)

protected:
    IFSpriteObject* pSuspend, *pSelect;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUIGuage : public FGUIObject
{
    friend class FGUI;

    FDECLARE_CLASS(FGUIGuage)

protected:
    IFSpriteObject* pValue;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUIPicture : public FGUIObject
{
    friend class FGUI;

    FDECLARE_CLASS(FGUIPicture)
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUIText : public FGUIObject
{
    friend class FGUI;

    FDECLARE_CLASS(FGUIText)

public:
    FGUIText();
    virtual void RenderText();

protected:
    DWORD nFont;
    DWORD nFntAlign;
    FString szText;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class FGUI : public IFMemObject
{
    FDECLARE_CLASS(FGUI);

public:
    FGUI(FGUIFunc func);
    ~FGUI();
    virtual FGUIObject* Add(EF_GUI_TYPE type, DWORD ui_id);
    virtual FGUIObject* Get(DWORD ui_id);
    virtual FGUIObject* Get(float cx, float cy);
    virtual float CX(){ return cursorx; }
    virtual float CY(){ return cursory; }
    virtual void Update();
    virtual void Render();
    virtual void RenderText();
    virtual void Release();
    virtual bool OnInput(FINPUT_PACKAGE& ipk);

protected:
    FGUIObject* pUIHead, * pUITail, * pFocus, * pSuspend;
    FGUIFunc pFunc;
    float cursorx, cursory;
};